import com.webobjects.foundation.*
import com.webobjects.eocontrol.*
import groovy.lang.webobjects.*

class NSDictionaryTest extends GroovyTestCase {
	static final MAP = [ one: 1, two: 2, three: 3 ]
	static final KEYS = [ "one", "two", "three" ]
	static final VALUES = [ 1, 2, 3 ]
	static final SUM = 6
	static final MAX = 3
	static final MIN = 1
	static final COUNT = 3
	static final DICT = new NSDictionary(MAP, true)
	
	void testCreation() {
		assert DICT instanceof NSDictionary
		
		NSDictionary d1 = MAP
		assert d1 instanceof NSDictionary
		def d2 = MAP as NSDictionary
		assert d2 instanceof NSDictionary
		def d3 = new NSDictionary(MAP)
		assert d3 instanceof NSDictionary
		def d4 = DICT as HashMap
		assert d4 instanceof HashMap
		assertEquals(d4, MAP)

		for (d in [ d1, d2, d3 ]) {
			assertEquals(d, DICT)
			check(d)
		}
	}
		
	void testSubscript() {
		checkSubscript(DICT, KEYS, VALUES)
	}
	
	void testValueForKey() {
		checkValueForKey(DICT, KEYS, VALUES)
	}
	
	void testGetAt() {
		def d1 = [ (KEYS): VALUES ]
		def d2 = d1 as NSDictionary
		def r1 = d1.getAt(KEYS)
		def r2 = d2.getAt(KEYS)
		def r3 = d1.getAt(VALUES)
		def r4 = d2.getAt(VALUES)
		
		assertEquals(r1, r2)
		assertEquals(r3, r4)
		
		assertEquals(r1, VALUES)
		assertEquals(r3, null)

		checkGetAt(DICT, KEYS, VALUES)
	}
	
	void testEach() {
		def r1 = 0 ; DICT.each { key, value -> r1 += value }
		def r2 = 0 ; MAP.each { key, value -> r2 += value }
		assertEquals(r1, r2)
		assertEquals(r1, SUM)
		
		def r3 = 0; DICT.each { entry -> r3 += entry.value }		
		def r4 = 0; MAP.each { entry -> r4 += entry.value }
		assertEquals(r3, r4)
		assertEquals(r3, SUM)
	}

	void testEachKey() {
		def r1 = []; DICT.eachKey { r1 << it }
		checkUnsortedArrayList(KEYS, r1)
	}
	
	void testEachValue() {
		def r1 = []; DICT.eachValue { r1 << it }
		checkUnsortedArrayList(VALUES, r1)
	}

	void testCollect() {
		def r1 = DICT.collect { item -> item.value }
		assert r1 instanceof NSArray
		def r2 = MAP.collect { item -> item.value }
		assert r2 instanceof ArrayList
		
		def r3 = DICT.collect { item -> item.key }
		assert r3 instanceof NSArray
		def r4 = MAP.collect { item -> item.key }
		assert r4 instanceof ArrayList

		checkUnsortedArrayList(r1, r2)
		checkUnsortedArrayList(r3, r4)
	}
	
	void testFind() {
		def r1 = DICT.find { entry -> entry.value == MAX }
		def r2 = MAP.find { entry -> entry.value == MAX }
		def r3 = DICT.find { entry -> entry.value > MAX }
		def r4 = MAP.find { entry -> entry.value > MAX }

		assertEquals(r1.value, r2.value)
		assertEquals(r3, null)
		assertEquals(r4, null)
	}
	
	void testFindAll() {
		def r1 = DICT.findAll { entry -> entry.value <= MAX }
		def r2 = MAP.findAll { entry -> entry.value <= MAX }
		def r3 = DICT.findAll { entry -> entry.value > MAX }
		def r4 = MAP.findAll { entry -> entry.value > MAX }

		assertEquals(r1.each{it.value}, r2.each{it.value})
		assertEquals(r3.each{it.value}, r4.each{it.value})
	}
	
	void testMap() {
		def r1 = DICT.map()
		assertEquals(MAP, r1)
		assert r1 instanceof Map
	}
	
	void testDictionaryByRemovingFromDictionaryKeysInArray() {
		def r1 = DICT.dictionaryByRemovingFromDictionaryKeysInArray(KEYS as NSArray)
		def r2 = DICT.dictionaryByRemovingFromDictionaryKeysInArray(KEYS)

		assertEquals(r1, [] as NSDictionary)
		assertEquals(r2, [] as NSDictionary)
	}
	
	void testDictionaryWithDictionary() {
		def d1 = new NSDictionary(KEYS as NSArray, VALUES as NSArray)
		def r1 = DICT.dictionaryWithDictionary(d1)
		
		def v1 = r1[ VALUES[0] ]
		assertEquals(v1, KEYS[0])
	}
	
	void testSortOrderings() {
		def a1 = [ [name: "bob", age: 20] as NSDictionary, 
		           		   [name: "zak", age: 15] as NSDictionary,
		           		   [name: "sue", age: 12] as NSDictionary ] as NSArray
		def d1 = [ age: EOSortOrdering.CompareAscending ] as NSDictionary
		def r1 = a1.sortedArrayUsingKeyOrderArray(d1.sortOrderings())
		def L1 = a1.arrayList()
		L1.sort{it.age}
		assertEquals(L1, r1)
		
		def d2 = [ name: EOSortOrdering.CompareAscending ] as NSDictionary
		def r2 = a1.sortedArrayUsingKeyOrderArray(d2.sortOrderings())
		def L2 = a1.arrayList()
		L2.sort{it.name}
		assertEquals(L2, r2)
	}
	
	private checkUnsortedArrayList(expected, result) {
		assertArrayEquals(expected.sort().toArray(), result.sort().toArray())
	}
	
	private checkValueForKey(dict, keys, expectedValues) {
		check(dict)
		//assertEquals(dict.valueForKey(keys[0]), expectedValues[0])
		def results = keys.collect { key -> dict.valueForKey(key) }
		assertEquals(expectedValues, results)
	}
	
	private checkSubscript(dict, keys, expectedValues) {
		check(dict)
		assertEquals(dict[keys[0]], expectedValues[0])
		def results = keys.collect { key -> dict[key] }
		assertEquals(expectedValues, results)
	}
	
	private checkGetAt(dict, keys, expectedValues) {
		check(dict)
		assertEquals(dict[keys[0]], expectedValues[0])
		def results = keys.collect { key -> dict.getAt(key) }
		assertEquals(expectedValues, results)
	}
	
	private check(dict) {
		assert dict instanceof NSDictionary
		assert dict != null
	}
}
